package net.ssta.core.db;

import java.sql.Connection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

class DBConnectionThreadLocal
{
	private static Logger logger = Logger.getLogger(DBConnectionThreadLocal.class);
	private static ThreadLocal<Map<Connection,StackTraceElement[]>> m_local = new ThreadLocal<Map<Connection,StackTraceElement[]>>();
	private DBConnectionThreadLocal(){}
	private static boolean m_bEnable = false;
	public static boolean enable()
	{
		return m_bEnable;
	}
	
	public static void enable(boolean bEnable)
	{
		m_bEnable = bEnable;
	}
	public static void addConnection(Connection conn)
	{
		try
		{
		if(m_bEnable == false || conn == null) return ;
		//
//		try
//		{
//			throw new Exception();//just throw a excption, so that we can get the call stack
//		}
//		catch(Exception e)
//		{
//			e.getStackTrace();
//			StringWriter sw = new StringWriter();
//			PrintWriter pw = new PrintWriter(sw, true);
//			e.printStackTrace(pw);
//			pw.flush();
//			sw.flush();
//			if(sw.toString().indexOf("com.hekit.common.db.DBConnectionMonitorFilter") < 0 ) return ;
//		}
		Map<Connection,StackTraceElement[]> map = m_local.get();
		if(map == null)
		{
			
			map = new HashMap<Connection,StackTraceElement[]>();
			m_local.set(map);
		}
		map.put(conn, new Throwable().getStackTrace());
		//StringBuffer sb = new StringBuffer();
		//sb.append("thread ").append(Thread.currentThread().getName()).append(" add connection " + conn.toString());
		//logger.info(sb.toString());
		}
		catch(Exception e)
		{
			//do nothing
		}
	}
	
	public static void closeConnection()
	{
		if(m_bEnable == false) return ;
		Map<Connection,StackTraceElement[]> map = m_local.get();
		if(map == null) return ;
		Iterator<Connection> it = map.keySet().iterator();
		StringBuffer sb = new StringBuffer();
		while(it.hasNext())
		{
			Connection conn = it.next();
			try
			{
				if(conn == null || conn.isClosed()) continue;
				StackTraceElement[] stack = map.get(conn);
				StackTraceElement element = stack[3];
				sb.setLength(0);
				sb.append("a connection was not closed, but it was alread closed automatically. this connection get at ");
				sb.append(element.getClassName()).append(".").append(element.getMethodName());
				sb.append("(").append(element.getFileName()).append(":").append(element.getLineNumber()).append(")");
				logger.warn(sb.toString());
				conn.close();
			}
			catch (Exception e)
			{
				e.printStackTrace();
			}
		}
		m_local.set(null);
	}
}
